package Pattern.StatePattern.Design;
/**
 * 状态模式：当一个对象的内在状态改变时允许改变其行为，这个对象看起来像是改变了其类。
 * 应用场景
 * 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中，可以把复杂的判断逻辑简化。
 * 三个角色
 * Context：它就是那个含有状态的对象，它可以处理一些请求，这些请求最终产生的响应会与状态相关。
 * State：状态接口，它定义了每一个状态的行为集合，这些行为会在Context中得以使用。
 * ConcreteState：具体状态，实现相关行为的具体状态类。
 *几个明显的优点：
 *                 一、我们去掉了if else结构，使得代码的可维护性更强，不易出错，这个优点挺明显，如果试图让你更改跑动的方法，是刚才的一堆if else好改，还是分成了若干个具体的状态类好改呢？答案是显而易见的.
 *                 二、使用多态代替了条件判断，这样我们代码的扩展性更强，比如要增加一些状态，假设有加速20%，加速10%，减速10%等等等（这并不是虚构，DOTA当中是真实存在这些状态的），会非常的容易。
 *                 三、状态是可以被共享的，这个在上面的例子当中有体现，看下Hero类当中的四个static final变量就知道了，因为状态类一般是没有自己的内部状态的，所有它只是一个具有行为的对象，因此是可以被共享的。
 *                 四、状态的转换更加简单安全，简单体现在状态的分割，因为我们把一堆if else分割成了若干个代码段分别放在几个具体的状态类当中，所以转换起来当然更简单，而且每次转换的时候我们只需要关注一个固定的状态到其他状态的转换。安全体现在类型安全，我们设置上下文的状态时，必须是状态接口的实现类，而不是原本的一个整数，这可以杜绝魔数以及不正确的状态码。
 *  状态模式也有它的缺点，不过它的缺点和大多数模式相似，有两点。
 *                   1、会增加的类的数量。
 *                   2、使系统的复杂性增加。
 *
 *         转自左潇龙博客：https://blog.csdn.net/zuoxiaolong8810/article/details/9775069
 *
 *         状态模式和策略模式的区别
 *   状态模式和策略模式有着相同的类图， 但是它们的意图不同。策略模式更加侧重于行为或算法的替换，并且可以在运行时动态的任意替换，侧重点是使用不同算法族来解决问题。而状态模式更加侧重于状态的改变影响改变行为，而行为的执行结果又会导致状态发生变化，是一个状态和行为的变化过程。策略模式需要客户端必须完全知晓所有的策略方法，才能够知道究竟哪一个策略是当前需要的。而状态模式客户端在使用的时候，可以不必关心有哪些状态，他只需要去调用环境的行为就可以了，在环境的内部维护了这些状态。
 */
public class DesignTest {
    public static void main(String[] args) throws InterruptedException {
        Hero hero = new Hero();
        hero.startRun();
        Thread.sleep(5000);
        hero.setState(Hero.SPEED_UP);
        Thread.sleep(5000);
        hero.setState(Hero.SPEED_DOWN);
        Thread.sleep(5000);
        hero.setState(Hero.SWIM);
        Thread.sleep(5000);
        hero.stopRun();
    }
}
